package com.bosssoft.hr.javase;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.*;

/**
 * @Description: 使用线程池进行文件下载
 * @Author: wengyu
 * @CreateTime: 2022/05/13 15:50
 */
public class DownloadFileThreadPool {

    private static final int TIME_OUT = 5000;

    private static final Long ALIVE_TIME = 60L;


    /**
     * @Author wengyu
     * @param urlLocation 请求路径
     * @param filePath 本机存放文件路径
     * @param corePoolSize 核心线程数
     * @param maxPoolSize 最大线程数
     * @throws IOException
     */
    public void getFileWithThreadPool(String urlLocation, String filePath,int corePoolSize, int maxPoolSize) throws IOException {

        ExecutorService threadPool = new ThreadPoolExecutor(corePoolSize, maxPoolSize,
                ALIVE_TIME, TimeUnit.SECONDS,
                new SynchronousQueue<>());

        // 获取文件长度
        long len = getContentLength(urlLocation);

        /**
         * 根据线程池的大小 对下载内容进行分段下载
         * start 计算分段下载开始的位置
         * end 计算分段下载结束的位置
         */
        for (int i = 0; i < maxPoolSize; i++) {
            long start = i * len / maxPoolSize;
            long end = (i + 1) * len / maxPoolSize - 1;
            if (i == maxPoolSize - 1) {
                end = len;
            }

            DownloadWithRange download = new DownloadWithRange(urlLocation, filePath, start,end);
            threadPool.execute(download);
        }
        threadPool.shutdown();
    }

    /**
     * @Author wengyu
     * @param urlLocation 请求路径
     * @return 文件长度
     * @throws IOException
     */
    public static long getContentLength(String urlLocation) throws IOException {
        URL url = null;

        if (urlLocation != null && !"".equals(urlLocation)) {
            url = new URL(urlLocation);
        }

        assert url != null;
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(TIME_OUT);
        conn.setRequestMethod("GET");
        return conn.getContentLength();
    }
}